from fastapi import APIRouter, Path, Query, Cookie, Header
from enum import Enum
from typing import Optional, List
from pydantic import BaseModel, Field
from datetime import date

app03 = APIRouter()
"""Path Parameters and Number Validations 路径参数和数字验证"""


@app03.get("/path/parameters")
def path_params01():
    return {"message": "This is a message"}


@app03.get("/path/{parameters}")
def path_params01(parameters: str):
    return {"message": "This is a message"}


class CityName(str, Enum):
    BeiJing = "Beijing China"
    ShangHai = "Shanghai China"


@app03.get("/enum/{city}")
async def latest(city: CityName):
    if city == city.ShangHai:
        return {"city_name": city, "confirmed": 1492, "death": 7}
    if city == city.BeiJing:
        return {"city_name": city, "confirmed": 971, "death": 9}
    return {"city_name": city, "latest": "unknow"}


@app03.get("/files/{file_path:path}")
def filepath(file_path: str):
    return f"The file path is {file_path}"


@app03.get("/path__/{num}")
def path_params_validate(num: int = Path(..., title="Your number", description="不可描述", ge=1, le=10)):
    return num


"""Query Parameters and String Validations 查询参数和字符串验证"""


@app03.get("/query")
def page_limit(page: int = 1, limit: Optional[int] = None):  # 给了默认值就是选填的参数，没给默认值就是必填参数
    if limit:
        return {"page": page, "limit": limit}
    return {"page": page}


@app03.get("/query/bool/conversion")
def type_conversion(param: bool = False):
    return param


@app03.get("/query/valiadtions")
def query_params_validate(
        value: str = Query(..., min_length=8, max_length=16, regex="^a"),
        values: List[str] = Query(default=["v1", "v2"], alias="alias_name")
):
    return value, values


"""Request Body and Fields 请求体和字段"""


class CityInfo(BaseModel):
    name: str = Field(..., example="Beijing")
    country: str
    country_code: str = None  # 给一个默认值
    country_population: int = Field(default=900, title="人口数量", description="国家的人口数量量", ge=900, le=1000)

    class Config:
        schema_extra = {
            "example": {
                "name": "Shanghai",
                "country": "China",
                "country_code": "CN",
                "country_population": 991
            }
        }


@app03.post("/request_body/city")
def city_info(city: CityInfo):
    print(city.name, city.country)
    return city.dict()


"""Request Body + Path parameters + Query parameters 多参数混合"""


@app03.put("/request_body/city/{name}")
def min_city_info(
        name: str,
        city01: CityInfo,
        city02: CityInfo,  # body可以定义多个
        confirmed: int = Query(ge=0, description="确诊数", default=0),
        death: int = Query(ge=0, description="死亡数", default=0)
):
    if name == "Shanghai":
        return {"Shanghai": {"confirmed": confirmed, "death": death}}
    return city01.dict(), city02.dict()


"""Request Body - Nested Models 数据格式嵌套的请求体"""


class Data(BaseModel):
    city: List[CityInfo] = None
    data: date
    confirmed: int = Field(ge=0, description="确诊数", default=0)
    deaths: int = Field(ge=0, description="死亡数", default=0)
    recovered: int = Field(ge=0, description="痊愈数", default=0)


@app03.put("request_body/nested")
def nested_models(data: Data):
    return data


"""Cookie 和 Header 参数"""


@app03.get("/cookie")
def cookie(cookie_id: Optional[str] = Cookie(None)):
    return {"cookie_id": cookie_id}


@app03.get("/header")
def header(user_agent: Optional[str] = Header(None, convert_underscores=True), x_token: List[str] = Header(None)):
    return {"User-Agent": user_agent, "x-token": x_token}
